﻿using CKS.PLC.Core.Cache;
using CKS.PLC.Core.Siemens;
using Infrastructure.Attribute;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SqlSugar;
using SqlSugar.IOC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Models.ProductionControl;
using ZR.Repository;

namespace CKS.PLC.Core
{
    /// <summary>
    /// PLC主调度服务，
    /// 功能：
    ///     读取PLC配置初始化plc客户端
    ///     启动PLC客户端线程
    /// </summary>
    [AppService(ServiceType = typeof(PlcMainService), ServiceLifetime = LifeTime.Singleton)]
    public class PlcMainService
    {
        private readonly ISqlSugarClient _dbSqlSugarClient;

        private readonly ILogger<PlcMainService> _logger;

        private readonly IServiceProvider _serviceProvider;

        private List<PlcConfig> plcConfigs = new List<PlcConfig>();

        private CancellationTokenSource cts;

        public PlcMainService(ILogger<PlcMainService> _logger, IServiceProvider _serviceProvider) { 
            this._dbSqlSugarClient = DbScoped.SugarScope.GetConnection(0);
            this._logger = _logger;
            this._serviceProvider = _serviceProvider;
        }

        /// <summary>
        /// 启动PLC监听服务
        /// </summary>
        public async Task StartAsync(CancellationToken cancellation)
        {
            cts = CancellationTokenSource.CreateLinkedTokenSource(cancellation);

            if (!CheckIsServer())
                return;

            //a.Id !=1 :不需要采集OP10，有其他程序采集

            plcConfigs = _dbSqlSugarClient.Queryable<PlcConfig>().ToList();
            _logger.LogWarning($"PlcMainService CurProductionLine：{PlcCache.CurProductionLine}");
            if (!string.IsNullOrEmpty(PlcCache.CurProductionLine)) {
                plcConfigs = plcConfigs.Where(o => o.ProductionLineCode == PlcCache.CurProductionLine).ToList();
            }

            if (plcConfigs.Count == 0)
            {
                _logger.LogWarning("PLC配置表未配置！");
                return;
            }

            await Task.Delay(1000);

            foreach (var config in plcConfigs)
            {
                try
                {
                    _ = Task.Factory.StartNew(() =>
                    {
                        var client = new S7NetClient(config, _serviceProvider);
                        // 将plcclient 加入到ioc
                        PlcCache.PlcClients.Add(client);
                        _ = client.StartAsync(cancellation);
                    }, TaskCreationOptions.LongRunning);
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"PLC{config.PlcAddress}异常 {ex.Message}！");
                }
            }
        }

        /// <summary>
        /// 判断当前程序是否在服务器运行
        /// </summary>
        /// <returns></returns>
        public bool CheckIsServer()
        {
            string ip = ToolsHelper.GetLocalIp().ToString();
            if (string.IsNullOrEmpty(ip))
            {
                _logger.LogWarning("服务器IP获取失败！");
                return false;
            }
            return true;
        }

    }
}
